﻿using System;
using System.Diagnostics;
using System.IO;
using System.Xml.Serialization;

[Serializable]
public class OrderDetails
{
    public string goods_name;
    public int goods_price;
    public string cus;
    public OrderDetails(string goods_name, int goods_price, string cus)
    {
        this.goods_name = goods_name;
        this.goods_price = goods_price;
        this.cus = cus;
    }

    //Equal方法重载
    public override bool Equals(object obj)
    {
        OrderDetails details = obj as OrderDetails;
        return details != null &&
               goods_name == details.goods_name &&
               goods_price == details.goods_price &&
               cus == details.cus;
    }
    public OrderDetails() { }
    //ToString方法重载
    public override string? ToString()
    {
        return "货物名：" + goods_name + " 客户：" + cus + " 订单金额：" + goods_price;
    }
}

[Serializable]
public class Order
{
    public int id;
    public OrderDetails OrderDetails;
    public int getid()
    {
        return id;
    }
    public string getname()
    {
        return OrderDetails.goods_name;
    }
    public string getcus()
    {
        return OrderDetails.cus;
    }
    public int getprice()
    {
        return OrderDetails.goods_price;
    }
    public void setOrderDetails(OrderDetails details)
    {
        OrderDetails = details;
    }
    public Order() { }
    public Order(int id, string goods_name, int goods_price, string cus)
    {
        this.id = id;
        OrderDetails new_det = new OrderDetails(goods_name, goods_price, cus);
        this.OrderDetails = new_det;
    }

    //Equal方法重载
    public override bool Equals(object obj)
    {
        Order new_order = obj as Order;
        return new_order != null &&
               id == new_order.id &&
               new_order.OrderDetails.Equals(OrderDetails);
    }

    //ToString方法重载
    public override string? ToString()
    {
        return "订单" + id + ": " + OrderDetails.ToString();
    }
}

public class OrderService
{
    public List<Order> Order_list;
    public OrderService()
    {
        Order_list = new List<Order>();
    }
    public void add(Order order)
    {
        if (Order_list != null)
            foreach (Order item in Order_list)
            {
                if (item.Equals(order)) return;//有重复订单信息时不加入
            }
        Order_list.Add(order);
    }
    public void addrange(List<Order> orders)
    {
        foreach(Order item in orders)
        {
            Order_list.Add(item);
        }
    }

    //按照订单id排序
    public void sort()
    {
        var tmp = from order in Order_list
                  orderby order.getid()
                  select order;
        List<Order> new_list = tmp.ToList();
        Order_list.Clear();
        Order_list.AddRange(new_list);
        new_list.Clear();

    }

    //修改，找不到id时throw异常
    public void alter(int id, string goods_name, int goods_price, string cus)
    {
        foreach (Order order in Order_list)
        {
            if (order.getid() == id)
            {
                OrderDetails tmp = new OrderDetails(goods_name, goods_price, cus);
                order.setOrderDetails(tmp);
                return;
            }
        }
        throw (new AlterFailException("no such id can be altered..."));
    }

    //利用linq完成搜索
    public bool search(string type, object data)
    {
        if (type == "id")
        {
            int sel_id = Convert.ToInt32(data);
            var list = Order_list.Where(s => s.getid() == sel_id).ToList();
            if(list==null) return false;
            foreach (var item in list)
            {
                Console.WriteLine(item.ToString());
            }
        }
        else if (type == "cus")
        {
            string cus = Convert.ToString(data);
            var list = Order_list.Where(s => s.getcus() == cus).ToList();
            if (list == null) return false;
            foreach (var item in list)
            {
                Console.WriteLine(item.ToString());
            }
        }
        else if (type == "name")
        {
            string name = Convert.ToString(data);
            var list = Order_list.Where(s => s.getname() == name).ToList();
            if (list == null) return false;
            foreach (var item in list)
            {
                Console.WriteLine(item.ToString());
            }
        }
        else if (type == "price")
        {
            int price = Convert.ToInt32(data);
            var list = Order_list.Where(s => s.getprice() == price).ToList();
            if (list == null) return false;
            foreach (var item in list)
            {
                Console.WriteLine(item.ToString());
            }
        }
        return true;
    }

    //删除操作
    public void delete(int id)
    {
        foreach (Order order in Order_list)
        {
            if (id == order.getid())
            {
                Order_list.Remove(order);
                return;
            }
        }
        throw (new DeleteFailException("no such id can be delected..."));
    }

    //导出
    public void export(string path)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
        using (FileStream fileStream = new FileStream(path,FileMode.Create))
        {
            xmlSerializer.Serialize(fileStream, Order_list);
        }
    }

    //导入
    public void import(string path)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
        using (FileStream fileStream = new FileStream(path, FileMode.Open))
        {
            List<Order> new_list = (List<Order>)xmlSerializer.Deserialize(fileStream);
            addrange(new_list);
        }
    }

}

//异常类
public class AlterFailException : ApplicationException
{
    public AlterFailException(string message) : base(message)
    {
    }
}

public class DeleteFailException : ApplicationException
{
    public DeleteFailException(string message) : base(message)
    {
    }
}

[Serializable]
public class A
{
    int a;
    public A() { }
    public A(int a) {
        this.a = a;
    }
}

[Serializable]
public class B
{
    int b;
    A a;
    public B() { }
    public B(int b,int a)
    {
        this.b = b;
        this.a = new A(a);
    }
}

public class Program
{
    static void Main(string[] args)
    {
        OrderService orderService = new OrderService();

        orderService.import("Order_Output.xml");
        Order o1 = new Order(4, "a", 100, "b");
        Console.WriteLine(o1.ToString());
        orderService.add(o1);
        Order o2 = new Order(7, "b", 200, "a");
        Order o3 = new Order(5, "c", 300, "d");
        Order o4 = new Order(6, "d", 400, "f");
        orderService.add(o2);
        orderService.add(o3);
        orderService.add(o4);

        orderService.sort();

        orderService.export("Order_Output.xml");
    }


}
